package com.cc.springboot_test.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class DateUtils {
    private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);
    public static final String DATE_JFP_STR = "yyyyMM";
    public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_MID_STR = "yyyyMMdd HH:mm:ss";
    public static final String DATE_SMALL_STR = "yyyy-MM-dd";
    public static final String DATE_KEY_STR = "yyMMddHHmmss";
    public static final String DATE_KEY_STR_FULL = "yyyyMMddHHmmss";
    public static final String DATE_STR = "yyyyMMdd";
    public static final String DATE_TIME_STR = "HHmmss";
    public static final String DATE_MILSECOND_STR = "yyMMddHHmmssSSS";
    public static final String DATE_MILSECOND_STR_FULL = "yyyyMMddHHmmssSSS";

    public static Date parse(String strDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);

        Date date = null;
        try {
            date = df.parse(strDate);
        } catch (ParseException e) {
            logger.error("解析日期异常：strDate：{}，pattern：{}", strDate, pattern);
        }
        return date;
    }

    public static Date parse(String strDate) {
        return parse(strDate, DateUtils.DATE_FULL_STR);
    }

    public static String formatDate(Date formatDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(formatDate);
    }

    public static String formatDateOrNull(Date formatDate, String pattern) {
        return formatDate == null ? null : formatDate(formatDate, pattern);
    }

    public static long dateToUnixTimestamp() {
        long timestamp = (new Date()).getTime();
        return timestamp;
    }

    public static long dateToUnixTimestamp(String date) {
        long timestamp = 0L;
        try {
            timestamp = (new SimpleDateFormat(DateUtils.DATE_FULL_STR)).parse(date).getTime();
        } catch (ParseException e) {
            logger.error("解析日期异常，strDate：{}，pattern：{}", date, DateUtils.DATE_FULL_STR);
        }
        return timestamp;
    }

    public static long dateToUnixTimestamp(String date, String pattern) {
        long timestamp = 0L;
        try {
            timestamp = (new SimpleDateFormat(pattern)).parse(date).getTime();
        } catch (ParseException e) {
            logger.error("解析日期异常，strDate：{}，pattern：{}", date, pattern);
        }
        return timestamp;
    }

    public static Timestamp dateToTimestamp(String date, String... patterns) {
        String[] arr$ = patterns;
        int len$ = patterns.length;

        for (int i$ = 0; i$ < len$; ++i$) {
            String pattern = arr$[i$];
            if (pattern.length() == date.length()) {
                try {
                    new Timestamp((new SimpleDateFormat(pattern)).parse(date).getTime());
                } catch (ParseException e) {
                    throw new RuntimeException("日期解析异常：" + date, e);
                }
            }
        }

        throw new RuntimeException("不支持的日期格式：" + date);
    }

    public static String unixTimestampToDate(long timestamp) {
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FULL_STR);
        df.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return df.format(new Date(timestamp));
    }

    public static int compareDateWithNow(Date target) {
        Date now = new Date();
        return target.compareTo(now);
    }

    public static int compareDateWithNow(long target) {
        long now = dateToUnixTimestamp();
        if (target > now) {
            return 1;
        } else {
            return target < now ? -1 : 0;
        }
    }

    public static int compareDateWith(Timestamp time1, Timestamp time2) {
        long t1 = time1.getTime();
        long t2 = time2.getTime();
        if (t1 > t2) {
            return 1;
        } else {
            return t1 < t2 ? -1 : 0;
        }
    }

    public static String getNowTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(new Date());
    }

    public static String getNowTime(String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        return df.format(new Date());
    }

    public static String getJFPTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
        return df.format(new Date());
    }

    public static int secondToMidnight() {
        Calendar now = Calendar.getInstance();
        Calendar tomorrow = new GregorianCalendar(now.get(1), now.get(2), now.get(5) + 1, 0, 0, 0);
        return (int) (tomorrow.getTimeInMillis() - now.getTimeInMillis()) / 1000;
    }

    public static Timestamp copyTimestamp(Timestamp timestamp) {
        return timestamp == null ? null : (Timestamp) timestamp.clone();
    }

    public static boolean sameDate(Timestamp a, Timestamp b) {
        Calendar ca = Calendar.getInstance();
        ca.setTimeInMillis(a.getTime());
        Calendar cb = Calendar.getInstance();
        cb.setTimeInMillis(b.getTime());
        return ca.get(1) == cb.get(1) && ca.get(2) == cb.get(2) && ca.get(5) == cb.get(5);
    }

    public static String getTodayStr() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.DATE_STR);
        String todayStr = simpleDateFormat.format(new Date());
        return todayStr;
    }

    public static String getMonthStr() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.DATE_JFP_STR);
        String monthStr = simpleDateFormat.format(new Date());
        return monthStr;
    }

    public static Long getLeftSeconds() {
        Date date = new Date();
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date);
        Calendar cal2 = Calendar.getInstance();
        cal2.add(6, 1);
        cal2.set(11, 0);
        cal2.set(12, 0);
        cal2.set(13, 0);
        return (cal2.getTimeInMillis() - cal1.getTimeInMillis()) / 1000L;
    }
}
